﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OracleCompare.Core;

namespace OracleCompare
{
    public partial class FrmMain : Form
    {
        private Timer t;

        public FrmMain()
        {
            InitializeComponent();
            tabControl1.TabPages.Remove(tpCompareResult);
            txtMsg.AppendText("欢迎使用数据库比较小工具，版权所有 @孔凡智" + "\n");
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            t = new Timer();
            t.Interval = 1000;
            t.Tick += new EventHandler(t_Tick);
        }

        #region 消息记录 LogMsg

        private delegate void InvokeMsg(string msg);

        /// <summary>
        /// 将消息输出到界面
        /// </summary>
        /// <param name="msg"></param>
        public void LogMsg(string msg)
        {
            if (txtMsg.InvokeRequired)
            {
                InvokeMsg im = new InvokeMsg(LogMsg);
                this.Invoke(im, new object[] { msg });
            }
            else
            {
                txtMsg.AppendText(">> " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ---> " + msg + "\n");
            }
        }

        private delegate void InvokeMsgExc(Exception msg);

        /// <summary>
        /// 将消息输出到界面
        /// </summary>
        /// <param name="msg"></param>
        public void LogMsg(Exception exc)
        {
            if (txtMsg.InvokeRequired)
            {
                InvokeMsgExc im = new InvokeMsgExc(LogMsg);
                this.Invoke(im, new object[] { exc });
            }
            else
            {
                string msg = string.IsNullOrEmpty(exc.Message) ? exc.ToString() : exc.Message;
                txtMsg.AppendText(">> " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ---> " + msg + "\n");
            }
        }

        private void tsmiClear_Click(object sender, EventArgs e)
        {
            txtMsg.Clear();
            txtMsg.AppendText("欢迎使用数据库比较小工具，版权所有 @孔凡智" + "\n");
        }

        private void txtMsg_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.A && e.Control)
            {
                txtMsg.SelectAll();
            }
        }

        #endregion

        #region 线程正在执行,控制其他空间可用性,ThreadRunning

        private delegate void InvokeRunning(bool IsRunning);

        public void ThreadRunning(bool IsRunning)
        {
            if (this.InvokeRequired)
            {
                InvokeRunning im = new InvokeRunning(ThreadRunning);
                this.Invoke(im, new object[] { IsRunning });
            }
            else
            {
                gpDbSettings.Enabled = !IsRunning;
                tabControl1.Enabled = !IsRunning;
                //panelRun.Enabled = !IsRunning;
                btnRun.Enabled = !IsRunning;
                btnCancel.Enabled = IsRunning;
            }
        }

        #endregion


        public delegate void InvokeComplete(bool ChangeToResult);

        private void CompareComplete(bool ChangeToResult)
        {
            if (this.InvokeRequired)
            {
                InvokeComplete _invoke = new InvokeComplete(CompareComplete);
                this.Invoke(_invoke, new object[] { ChangeToResult });
            }
            else
            {
                t.Enabled = false;

                btnRun.Text = "执行";
                btnRun.Tag = 0;

                if (ChangeToResult)
                {
                    if (!tabControl1.TabPages.Contains(tpCompareResult))
                    {
                        tabControl1.TabPages.Add(tpCompareResult);
                    }

                    tabControl1.SelectedTab = tpCompareResult;
                }
            }
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            t.Start();
            bwCompare.RunWorkerAsync();
        }

        void t_Tick(object sender, EventArgs e)
        {
            CaculateTime();
        }

        public delegate void InvokeTime();

        public void CaculateTime()
        {
            if (this.InvokeRequired)
            {
                InvokeTime _invoke = new InvokeTime(CaculateTime);
                this.Invoke(_invoke, null);
            }
            else
            {
                int i = 0;
                try
                {
                    i = Convert.ToInt32(btnRun.Tag);
                }
                catch
                { i = 0; }

                i = i + 1;
                btnRun.Tag = i;
                btnRun.Text = i.ToString();
            }
        }

        private void bwCompare_DoWork(object sender, DoWorkEventArgs e)
        {
            ThreadRunning(true);
            try
            {
                Compare();
            }
            catch (Exception exc)
            {
                LogMsg(exc);
            }
        }

        private void bwCompare_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            CompareComplete(true);
            ThreadRunning(false);
        }

        private void Compare()
        {
            string strIsCompareContent = System.Configuration.ConfigurationManager.AppSettings["IsCompareContent"];
            CompareUtiity ce = new CompareUtiity(txtSer1.Text, txtUser1.Text, txtPwd1.Text,
                txtSer2.Text, txtUser2.Text, txtPwd2.Text, ckTable.Checked, ckView.Checked, ckProc.Checked,
                txtTableCon.Text, txtViewCon.Text, txtProcCon.Text,
                txtTableUnCon.Text, txtViewUnCon.Text, txtProcUncon.Text,
                this, (strIsCompareContent == "1" ? true : false));
            List<CompareEntity> result = ce.Compare();
            BindingData(result);
        }

        private delegate void InvokeBindingData(List<CompareEntity> result);

        private void BindingData(List<CompareEntity> result)
        {
            if (this.InvokeRequired)
            {
                InvokeBindingData _invoke = new InvokeBindingData(BindingData);
                this.Invoke(_invoke, new object[] { result });
            }
            else
            {
                gvResult.DataSource = null;
                gvResult.DataSource = result;
            }
        }

        #region 测试配置

        /// <summary>
        /// 测试配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTest_Click(object sender, EventArgs e)
        {
            bwTestConfig.RunWorkerAsync();
        }

        private void bwTestConfig_DoWork(object sender, DoWorkEventArgs e)
        {
            ThreadRunning(true);

            OracleHelper oh = new OracleHelper(txtSer1.Text, txtUser1.Text, txtPwd1.Text);
            try
            {
                LogMsg("开始对第一个数据库设置进行测试...");
                oh.TestConfig();
                LogMsg("数据库设置正确.");
            }
            catch (Exception exc)
            {
                LogMsg(exc.ToString());
            }

            oh = new OracleHelper(txtSer2.Text, txtUser2.Text, txtPwd2.Text);
            try
            {
                LogMsg("开始对第二个数据库设置进行测试...");
                oh.TestConfig();
                LogMsg("数据库设置正确.");
            }
            catch (Exception exc)
            {
                LogMsg(exc);
            }
        }

        private void bwTestConfig_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ThreadRunning(false);
        }

        #endregion

        /// <summary>
        /// 交换数据库设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChange_Click(object sender, EventArgs e)
        {
            string temp = txtSer1.Text;
            txtSer1.Text = txtSer2.Text;
            txtSer2.Text = temp;

            temp = txtUser1.Text;
            txtUser1.Text = txtUser2.Text;
            txtUser2.Text = temp;

            temp = txtPwd1.Text;
            txtPwd1.Text = txtPwd2.Text;
            txtPwd2.Text = temp;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            bwCompare.CancelAsync();
            bwCompare.Dispose();
            t.Enabled = false;
            ThreadRunning(false);
            CompareComplete(false);
            LogMsg("比较工作未完成，主动停止比较操作.");
        }
    }
}
